#include "StdAfx.h"
#include "type.h"
#include "Chunk.h"
#include "ChunkLoader.h"
#include "ChunkManager.h"
#include "ChunkCamera.h"
#include "ChunkSpace.h"
#include "ChunkFileSerializer.h"

using namespace ChunkSystem;
using namespace Common;


ChunkSeeker::ChunkSeeker(void)
	:m_pFoundSeed(NULL)
{
}

ChunkSeeker::~ChunkSeeker(void)
{
}

bool ChunkSeeker::canHandleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ)
{
	if( req == NULL ||  req->getChannel() != m_gChunkSeekChannel || srcQ == NULL )
		return false;
	
	return true;
}

WorkQueue::Response* ChunkSeeker::handleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ)
{
	if( req == NULL )
		return NULL;
	
	ChunkSeekRequestData pSeekData = any_cast< ChunkSeekRequestData >( req->getData() );
	//encoding the pos into chunk grid coord
	Vector3 vSeekPos = pSeekData.m_vTargetPos;
	ChunkSpace*  pCurChunkSpace = pSeekData.m_pWorkSpace;
	ChunkFileSerializer* pChunkFileSerializer = pSeekData.m_pChunkFileSerializer;
	if( pCurChunkSpace == NULL || pChunkFileSerializer == NULL )
		return NULL;

	Chunk* pFindChunk = pCurChunkSpace->CreateChunkFromChunkFile( vSeekPos , pChunkFileSerializer );
	if( pFindChunk == NULL )
	{
		//TODO:if creation failed, we would correct it
		return NULL;
	}

	m_pFoundSeed = pFindChunk;

	return NULL;

	//TODO: try different way later;

	//WorkQueue::Response* pResponse = new WorkQueue::Response( req , true , Any(pFindChunk) );
	//return pResponse;
}

Chunk*	ChunkSeeker::GetFoundSeed(void) const
{
	return m_pFoundSeed;
}

void ChunkSeeker::ResetSeed(void)
{
	m_pFoundSeed = NULL;
}

ChunkSeekResponseHandler::ChunkSeekResponseHandler(void)
{
}

ChunkSeekResponseHandler::~ChunkSeekResponseHandler(void)
{
}

bool ChunkSeekResponseHandler::canHandleResponse(const WorkQueue::Response* response, const WorkQueue* srcQ)
{
	if( response && response->getRequest()->getChannel() == m_gChunkSeekChannel )
		return true;

	return false;
}

void ChunkSeekResponseHandler::handleResponse(const WorkQueue::Response* response, const WorkQueue* srcQ)
{
	Chunk* pFoundChunk = any_cast<Chunk*>( response->getData() );

}

ChunkLoader::ChunkLoader()
{
}
ChunkLoader::~ChunkLoader()
{
}

bool ChunkLoader::canHandleRequest(const Common::WorkQueue::Request* req, const Common::WorkQueue* srcQ)
{
	if( req == NULL ||  req->getChannel() != m_gChunkLoadChannel || srcQ == NULL )
		return false;
	
	return true;
}

WorkQueue::Response* ChunkLoader::handleRequest(const Common::WorkQueue::Request* req, const Common::WorkQueue* srcQ)
{
	assert( req != NULL );

	ChunkLoadRequestData pLoadData = any_cast<ChunkLoadRequestData>( req->getData() );

	Chunk* pLoadTarget = pLoadData.m_pLoadTarget;
	ChunkFileSerializer* pChunkFileSerializer = pLoadData.m_pChunkFileSerializer;

	String strChunkPath;

	std::stringstream ss;
	ss << ChunkManager::GetInstance().GetResPath() << "/" << ChunkManager::GetInstance().GetSpacePath() << "/" << pLoadTarget->GetId() << ".chunk";
	ss >> strChunkPath;
	TiXmlElement* pChunkRoot = pChunkFileSerializer->GetChunkRoot( strChunkPath );
	assert( pChunkRoot != NULL );

	Chunk::State& rChunkState = pLoadTarget->GetCurState();
	assert( rChunkState == Chunk::eLoading );

	if( !pLoadTarget->Load( pChunkRoot ) )
	{
		rChunkState = Chunk::eUnload;
		return new WorkQueue::Response( req , false , Any() );
	}
	
	rChunkState = Chunk::eLoaded;

	return new WorkQueue::Response( req , true , Any() );
}

